package kuang.juc.pc;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 指定通知对象，实现顺序调用
 */
public class Juc_B {
    public static void main(String[] args) {

        Data3 data = new Data3();

        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                data.printA();
            }
        },"A").start();

        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                data.printB();
            }
        },"B").start();

        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                data.printC();
            }
        },"C").start();
    }
}
class Data3{
    private Lock lock =new ReentrantLock();
    //printA的监视器
    private Condition conditionA = lock.newCondition();
    //printB的监视器
    private Condition conditionB = lock.newCondition();
    //printC的监视器
    private Condition conditionC = lock.newCondition();

    private int number=0;

    public void printA(){
        //上锁
        lock.lock();
        //业务代码
        try {
            //while循环判断，防止虚假唤醒，不能用if
            while (number!=0)
                conditionA.await();
            number=1;
            System.out.println(Thread.currentThread().getName()+"=>AAAAAA");
            //通知监视器B
            conditionB.signal();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //释放锁
            lock.unlock();
        }
    }

    public void printB(){
        //上锁
        lock.lock();
        //业务代码
        try {
            //while循环判断，防止虚假唤醒，不能用if
            while (number!=1)
                conditionB.await();
            number=2;
            System.out.println(Thread.currentThread().getName()+"=>BBBBBB");
            //通知监视器C
            conditionC.signal();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //释放锁
            lock.unlock();
        }
    }

    public void printC(){
        //上锁
        lock.lock();
        //业务代码
        try {
            //while循环判断，防止虚假唤醒，不能用if
            while (number!=2)
                conditionC.await();
            number=0;
            System.out.println(Thread.currentThread().getName()+"=>CCCCCC");
            //通知监视器C
            conditionA.signal();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //释放锁
            lock.unlock();
        }
    }
}
